import PropTypes from '@/utils/PropTypes'
import {
  defineComponent,
  ref,
  h,
  toRefs,
  onUnmounted,
  watch,
  markRaw,
} from 'vue'
import { Row, Col, Form, Space, Button, FormInstance } from 'ant-design-vue'
import dayjs from 'dayjs'
import { debounceHandlerFun } from '@/utils/lodash'
type T =
  | 'string'
  | 'number'
  | 'boolean'
  | 'method'
  | 'regexp'
  | 'integer'
  | 'float'
  | 'array'
  | 'object'
  | 'enum'
  | 'date'
  | 'url'
  | 'hex'
  | 'email'
  | 'any'
type Rule = {
  required?: boolean
  message?: string
  trigger?: string
  validator?: (rule: Rule, value: any) => Promise<void> | void
  enum?: string
  len?: number
  max?: number
  min?: number
  pattern?: RegExp
  type?: T
  transform?: (value: any) => any
  whitespace?: boolean
}
type FormParamType = {
  label: string
  name: string
  type: any
  component: any
  value?: any
  width?: string
  placeholder?: string
  options?: any[]
  suffix?: string
  fieldNames?: { label: string; value: string }
  lg?: number
  md?: number
  push?: number
  rows?: number
  rules?: Rule[]
  children?: FormParamType[]
  isShow?: boolean
  func?: (value: any) => void
}
type K = 'horizontal' | 'vertical' | 'inline'
export default defineComponent({
  name: 'formCom',
  props: {
    formRefs: PropTypes.object().def(),
    layout: PropTypes.strOption<K>().def('horizontal'),
    formParam: PropTypes.array<FormParamType>().def([]),
    formState: PropTypes.object().def({}),
    labelCol: PropTypes.object().def({ span: 7 }),
    wrapperCol: PropTypes.object().def({ span: 16 }),
    labelWrap: PropTypes.bool().def(false),
  },
  emits: ['update:formState', 'update:formRefs'],
  setup(props, { slots, emit }) {
    const { labelWrap, formParam, formState, labelCol, wrapperCol } =
      toRefs(props)
    const formRef = ref<FormInstance>()
    onUnmounted(() => {
      emit('update:formState', formState.value)
    })
    // const getValue = (rest: any) => {
    //   const arr = []
    //   if (rest.type == 'RangePicker' || rest.type == 'DatePicker') {
    //     if (rest.value && rest.value.length) {
    //       arr.push(dayjs(formState.value[rest.value[0]]))
    //       // arr.push(dayjs(formState.value[rest.value[1]]))
    //     }
    //     return arr
    //   } else {
    //     return formState.value[rest.name]
    //   }
    // }
    watch(
      () => formRef.value,
      () => {
        emit('update:formRefs', formRef.value)
      },
    )
    return () => (
      <div>
        <Form
          ref={formRef}
          model={formState.value}
          layout={props.layout}
          labelCol={labelCol.value}
          wrapperCol={wrapperCol.value}
          labelWrap={labelWrap.value}
        >
          <Row>
            {formParam.value.map((v: any, index) => {
              const { children, ...rest } = v
              return (
                <>
                  {rest.isShow && (
                    <Col
                      lg={{ span: v.lg || 12 }}
                      md={{ span: v.md || 12 }}
                      push={rest.push || 0}
                      pull={rest.pull || 0}
                    >
                      <Form.Item
                        label={rest.label}
                        name={rest.name}
                        labelCol={rest.labelCol}
                        wrapperCol={rest.wrapperCol}
                        help={rest.help}
                        extra={rest.extra}
                        rules={rest.rules}
                        colon={rest.colon}
                      >
                        {rest.type == 'html' ? (
                          h(
                            rest.component,
                            { style: { width: rest.width, ...rest.style } },
                            formState.value[rest.name],
                          )
                        ) : (
                          <>
                            {h(
                              markRaw(rest.component), // 组件类型
                              {
                                ...rest,
                                style: { width: rest.width, ...rest.style },
                                placeholder:
                                  rest.placeholder && rest.placeholder,
                                value: formState.value[rest.name],
                                onInput: (e: any) => {
                                  if (rest.name == 'RangePicker') return
                                  formState.value[rest.name] = e.target.value
                                },
                                onChange: (e: any) => {
                                  if (rest.type == 'Select') {
                                    formState.value[rest.name] = e
                                    rest.func && rest.func()
                                    return
                                  }
                                  if (rest.type == 'DatePicker') {
                                    formState.value[rest.value[0]] =
                                      e && dayjs(e).format(rest.formate)
                                    formState.value[rest.name] = e
                                    return
                                  }
                                  if (rest.type == 'RangePicker') {
                                    debounceHandlerFun(() => {
                                      formState.value[rest.value[0]] = dayjs(
                                        e[0],
                                      ).format(rest.formate)
                                      formState.value[rest.value[1]] = dayjs(
                                        e[1],
                                      ).format(rest.formate)
                                    }, rest.delay)
                                  }
                                },
                              },
                            )}
                            {children &&
                              children.map((item: any) =>
                                h(
                                  markRaw(item.component), // 组件类型
                                  {
                                    style: { width: item.width, ...item.style },
                                    name: item.name,
                                    options: item.options,
                                    placeholder:
                                      item.placeholder && item.placeholder,
                                    value: formState.value[item.name],
                                    onInput: (e: any) => {
                                      formState.value[item.name] =
                                        e.target.value
                                    },
                                    onChange: (e: any) => {
                                      console.log(item.type, e)
                                      if (item.type != 'Select') return
                                      formState.value[item.name] = e
                                    },
                                  },
                                ),
                              )}
                          </>
                        )}
                      </Form.Item>
                    </Col>
                  )}
                </>
              )
            })}
          </Row>
          {slots.extra && slots.extra()}
        </Form>
      </div>
    )
  },
})
